/**
 * 
 */
package com.nari.heatassist.service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

import com.nari.baseinfo.dao.IHeatRoomDao;
import com.nari.baseinfo.model.IBuilding;
import com.nari.baseinfo.model.IHeatMeter;
import com.nari.heatassist.dao.IBuildingConsumeConfigDao;
import com.nari.heatassist.utils.ConsumeStatisReportUtil;
import com.nari.heatassist.utils.ReportBuildupData;
import com.nari.heatshare.dao.IHeatMeterDataGatherDao;
import com.nari.platform.date.CalendarConstants;
import com.nari.platform.date.CalendarUtils;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.utils.NumberSystemConversion;

/**
 * 
 * @author Xiaopeng
 * @date 2014-4-28
 */
public class BuildingConsumeStatisServiceImpl implements IBuildingConsumeStatisService {
	private IBuildingConsumeConfigDao iBuildingConsumeConfigDao;
	private IHeatMeterDataGatherDao iHeatMeterDataGatherDao;
	private IHeatRoomDao iHeatRoomDao;
	
	/**
	 * 查询楼栋对应时段的耗热报表数据
	 * @param buildingList
	 * @param startDate
	 * @param endDate
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	public ReportBuildupData queryBuildingConsumeReport(List<IBuilding> buildingList, Date startDate, 
			Date endDate) throws Exception {
		//报表数据
		StringBuffer reportData = new StringBuffer("");
		//配置异常的楼栋信息
		StringBuffer problemBuildingConfig = new StringBuffer("");
		if(buildingList!=null && buildingList.size()>0) {
			for(IBuilding building: buildingList) {
				//查询楼栋的热表配置
				int measureMeterCounter = iBuildingConsumeConfigDao.countBuildingMeasureMeterNum(building.getId());
				if(measureMeterCounter == 0) {
					problemBuildingConfig.append(building.getBuildingID());
					problemBuildingConfig.append("、");
				} else {
					String buildingPerConsume = this.calcBuildingPerConsumeFormat(building, startDate, endDate);
					String buildingReport = ConsumeStatisReportUtil.gen2DReportData(building.getBuildingID(), buildingPerConsume);
					reportData.append(buildingReport);
				}
			}
		}
		//报告楼栋异常配置
		ResponseMsg rmsg = ResponseMsg.getInstance(true, "");
		if(problemBuildingConfig.length() > 0) {
			rmsg = ResponseMsg.getInstance(false, problemBuildingConfig.substring(0, problemBuildingConfig.length()-1));
		}
		return ReportBuildupData.getInstance(rmsg, reportData.toString());
	}
	
	/**
	 * 查询楼栋对应时段的耗热报表数据，依据统计频率查询对应的报表数据
	 * @param building
	 * @param startDate
	 * @param endDate
	 * @param timeFrequence 统计频率
	 * permonth：每月	peryear：每年
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-29
	 */
	public ReportBuildupData queryBuildingConsumeReport(IBuilding building, Date startDate, 
			Date endDate, String timeFrequence) throws Exception {
		//报表数据
		StringBuffer reportData = new StringBuffer("");
		//查询楼栋的热表配置
		int measureMeterCounter = iBuildingConsumeConfigDao.countBuildingMeasureMeterNum(building.getId());
		//报告楼栋异常配置
		ResponseMsg rmsg = ResponseMsg.getInstance(true, "");
		if(measureMeterCounter == 0) {
			rmsg = ResponseMsg.getInstance(false, building.getBuildingID());
		} else {
			//年度统计
			if("peryear".equals(timeFrequence)) {
				//时段在同一年
				if(CalendarUtils.getYearFromCal(startDate) == CalendarUtils.getYearFromCal(endDate)) {
					String buildingPerConsume = this.calcBuildingPerConsumeFormat(building, startDate, endDate);
					String reportLabel = CalendarUtils.parseDateToString(startDate, "yyyy");
					String buildingReport = ConsumeStatisReportUtil.gen2DReportData(reportLabel, buildingPerConsume);
					reportData.append(buildingReport);
				} else { //时段不在同一年
					int startYear = CalendarUtils.getYearFromCal(startDate);
					int endYear = CalendarUtils.getYearFromCal(endDate);
					while(CalendarUtils.getYearFromCal(startDate) <= endYear) {
						Date reportStartDate = null;
						Date reportEndDate = null;
						//获取报表起止日期
						int currYear = CalendarUtils.getYearFromCal(startDate);
						if(currYear == startYear) {
							reportStartDate = startDate;
							reportEndDate = CalendarUtils.parseStringToDate(currYear+"-12-31");
						} else if(currYear>startYear && currYear<endYear) {
							reportStartDate = CalendarUtils.parseStringToDate(currYear+"-01-01");
							reportEndDate = CalendarUtils.parseStringToDate(currYear+"-12-31");
						} else if(currYear == endYear) {
							reportStartDate = CalendarUtils.parseStringToDate(currYear+"-01-01");
							reportEndDate = endDate;
						}
						//根据起止日期统计楼栋单位耗热量报表
						String buildingPerConsume = this.calcBuildingPerConsumeFormat(building, reportStartDate, reportEndDate);
						String reportLabel = CalendarUtils.parseDateToString(reportStartDate, "yyyy");
						String buildingReport = ConsumeStatisReportUtil.gen2DReportData(reportLabel, buildingPerConsume);
						reportData.append(buildingReport);
						//年度累加
						startDate = CalendarUtils.addYears(startDate, 1);
					}
				}
			}
			//月度统计
			if("permonth".equals(timeFrequence)) {
				//时段在同一月
				if(CalendarUtils.parseDateToString(startDate, "yyyyMM").equals(CalendarUtils.parseDateToString(endDate, "yyyyMM"))) {
					String buildingPerConsume = this.calcBuildingPerConsumeFormat(building, startDate, endDate);
					String reportLabel = CalendarUtils.parseDateToString(startDate, "yyyy.MM");
					String buildingReport = ConsumeStatisReportUtil.gen2DReportData(reportLabel, buildingPerConsume);
					reportData.append(buildingReport);
				} else { //时段不在同一月
					int startMonth = Integer.valueOf(CalendarUtils.parseDateToString(startDate, "yyyyMM"));
					int endMonth = Integer.valueOf(CalendarUtils.parseDateToString(endDate, "yyyyMM"));
					while(Integer.valueOf(CalendarUtils.parseDateToString(startDate, "yyyyMM")) <= endMonth) {
						Date reportStartDate = null;
						Date reportEndDate = null;
						//获取报表起止日期
						int currMonth = Integer.valueOf(CalendarUtils.parseDateToString(startDate, "yyyyMM"));
						if(currMonth == startMonth) {
							reportStartDate = startDate;
							//当月总天数
							int dayNumbers = CalendarUtils.getNumberOfDaysInMonth(CalendarUtils.getYearFromCal(startDate), CalendarUtils.getMonthFromCal(startDate));
							reportEndDate = CalendarUtils.parseStringToDate(currMonth+""+dayNumbers, CalendarConstants.dateFormat_stamp);
						} else if(currMonth>startMonth && currMonth<endMonth) {
							reportStartDate = CalendarUtils.parseStringToDate(currMonth+"01", CalendarConstants.dateFormat_stamp);
							//当月总天数
							int dayNumbers = CalendarUtils.getNumberOfDaysInMonth(CalendarUtils.getYearFromCal(startDate), CalendarUtils.getMonthFromCal(startDate));
							reportEndDate = CalendarUtils.parseStringToDate(currMonth+""+dayNumbers, CalendarConstants.dateFormat_stamp);
						} else if(currMonth == endMonth) {
							reportStartDate = CalendarUtils.parseStringToDate(currMonth+"01", CalendarConstants.dateFormat_stamp);
							reportEndDate = endDate;
						}
						//根据起止日期统计楼栋单位耗热量报表
						String buildingPerConsume = this.calcBuildingPerConsumeFormat(building, reportStartDate, reportEndDate);
						String reportLabel = CalendarUtils.parseDateToString(reportStartDate, "yyyy.MM");
						String buildingReport = ConsumeStatisReportUtil.gen2DReportData(reportLabel, buildingPerConsume);
						reportData.append(buildingReport);
						//月度累加
						startDate = CalendarUtils.addMonths(startDate, 1);
					}
				}
			}
		}
		return ReportBuildupData.getInstance(rmsg, reportData.toString());
	}
	
	/**
	 * 计算楼栋单位耗热数据(MWh/㎡)
	 * @param building
	 * @param startDate
	 * @param endDate
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	private String calcBuildingPerConsumeFormat(IBuilding building, Date startDate, 
			Date endDate) throws Exception {
		List<IHeatMeter> addTypeHeatMeters = iBuildingConsumeConfigDao.queryMeasureMetersByBuildingUID(building.getId(), "add");
		//计和的热表计量值
		double addTypeMeasureData = this.calcMetersMeasureDataMWh(addTypeHeatMeters, startDate, endDate);
		//计差热表
		List<IHeatMeter> subsTypeHeatMeters = iBuildingConsumeConfigDao.queryMeasureMetersByBuildingUID(building.getId(), "subs");
		//计差的热表计量值
		double subsTypeMeasureData = this.calcMetersMeasureDataMWh(subsTypeHeatMeters, startDate, endDate);
		//楼栋耗热计量值
		double measureData = new BigDecimal(addTypeMeasureData)
				.subtract(new BigDecimal(subsTypeMeasureData))
				.doubleValue();
		//楼栋面积
		double buildingArea = iHeatRoomDao.sumRoomStructAreaByBelongs(null, null, building.getId(), null, null);
		//计算楼栋单位面积耗热量
		double perAreaConsume = 0;
		if(NumberSystemConversion.compareFloatValue(buildingArea, 0) > 0) {
			perAreaConsume = new BigDecimal(measureData)
					.divide(new BigDecimal(buildingArea), new MathContext(4, RoundingMode.HALF_UP))
					.doubleValue();
		}
		return NumberSystemConversion.formatToDecimalNumber(perAreaConsume);
	}
	
	/**
	 * 计算热表的计量数据的统计和
	 * @param measureMeterList
	 * @param startDate
	 * @param endDate
	 * @return 返回计量热量的热量单位为MWh
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-4-28
	 */
	public double calcMetersMeasureDataMWh(List<IHeatMeter> measureMeterList, Date startDate, 
			Date endDate) throws Exception {
		BigDecimal measureData = new BigDecimal("0");
		if(measureMeterList!=null && measureMeterList.size()>0) {
			for(IHeatMeter measureMeter: measureMeterList) {
				double singleMeasureData = iHeatMeterDataGatherDao.calcMeterMeasureDataMWhByPeriod(measureMeter.getMeterNo(), startDate, endDate);
				measureData = measureData.add(new BigDecimal(singleMeasureData));
			}
		}
		return measureData.doubleValue();
	}

	/**
	 * @return the iBuildingConsumeConfigDao
	 */
	public IBuildingConsumeConfigDao getiBuildingConsumeConfigDao() {
		return iBuildingConsumeConfigDao;
	}

	/**
	 * @param iBuildingConsumeConfigDao the iBuildingConsumeConfigDao to set
	 */
	public void setiBuildingConsumeConfigDao(
			IBuildingConsumeConfigDao iBuildingConsumeConfigDao) {
		this.iBuildingConsumeConfigDao = iBuildingConsumeConfigDao;
	}

	/**
	 * @return the iHeatMeterDataGatherDao
	 */
	public IHeatMeterDataGatherDao getiHeatMeterDataGatherDao() {
		return iHeatMeterDataGatherDao;
	}

	/**
	 * @param iHeatMeterDataGatherDao the iHeatMeterDataGatherDao to set
	 */
	public void setiHeatMeterDataGatherDao(
			IHeatMeterDataGatherDao iHeatMeterDataGatherDao) {
		this.iHeatMeterDataGatherDao = iHeatMeterDataGatherDao;
	}

	/**
	 * @return the iHeatRoomDao
	 */
	public IHeatRoomDao getiHeatRoomDao() {
		return iHeatRoomDao;
	}

	/**
	 * @param iHeatRoomDao the iHeatRoomDao to set
	 */
	public void setiHeatRoomDao(IHeatRoomDao iHeatRoomDao) {
		this.iHeatRoomDao = iHeatRoomDao;
	}

}
